﻿using System;
using System.Collections.Generic;

namespace Wrox.ProCSharp.Delegates
{
    class Program
    {
        static void Main()
        {
            SimpleDemos();
            ClosureWithModification();
            ClosureWithForEach();
        }


        static void SimpleDemos()
        {
            //nameof 表达式可生成变量、类型或成员的名称作为字符串常量：
            Console.WriteLine(nameof(SimpleDemos));
            Func<string, string> oneParam = s => $"change uppercase {s.ToUpper()}";//当前字符串的大写形式
            Console.WriteLine(oneParam("test"));

            Func<double, double, double> twoParams = (x, y) => x * y;//x,y参数.x*y返回值
            Console.WriteLine(twoParams(3, 2));         
            Func<double, double, double> twoParamsWithTypes = (double x, double y)/*参数可以确定类型与上面语句一样*/ => x * y;
            Console.WriteLine(twoParamsWithTypes(4, 2));

            Func<double, double> operations = x => x * 2;
            operations += x => x * x;//多播,多加入了一个自身相乘方法(有点类似代替了之前的方法)

            ProcessAndDisplayNumber(operations, 2.0);
            ProcessAndDisplayNumber(operations, 7.94);
            ProcessAndDisplayNumber(operations, 1.414);
            Console.WriteLine();
        }

        static void ProcessAndDisplayNumber(Func<double, double> action, double value)
        {
            double result = action(value);
            Console.WriteLine($"Value is {value}, result of operation is {result}");
        }

        static void ClosureWithModification()
        {
            Console.WriteLine(nameof(ClosureWithModification));
            int someVal = 5;
            Func<int, int> f = x => x + someVal;

            someVal = 7;

            Console.WriteLine(f(3));
            Console.WriteLine();
        }

        static void ClosureWithForEach()
        {
            Console.WriteLine(nameof(ClosureWithForEach));
            var values = new List<int>() { 10, 20, 30 };
            var funcs = new List<Func<int>>();//创建了一个（Func无参,返回值为int）的list委托对象
            foreach (var val in values)
            {
                funcs.Add(()/*无参的方法*/ => val/*返回值为每一个数组的元素*/);
            }
            foreach (var f in funcs)
            {
                Console.WriteLine(f());
            }
            Console.WriteLine();
        }
    }
}
